public with sharing class CheckExpiryDate {
    public void sendNotification(){
        try
        {
            List<Certificate_Data__c> CertificateData;
            CertificateData = [SELECT Expiry_date__c, Item__c, Pass__c, Test_Date__c FROM Certificate_Data__c LIMIT 50000];
            List<Item__c> Items = [SELECT id,name,Item_Group__c,Number_of_Pins__c,Version__c,Serial_Number__c,Description__c,CreatedById FROM Item__c LIMIT 50000];
            List<User> Users = [SELECT id,name,Email,CreatedById FROM User LIMIT 50000];
            Map<Id,Item__c> ItemsMap = new Map<Id,Item__c>();
            Map<Id,User> UserMap = new Map<Id,User>();
            if(CertificateData != Null)
            {
                if(Items!= Null && Users != Null)
                {
                    for(Item__c item : Items)
                    {
                        ItemsMap.put(item.id,item);
                    }
                    for(User usr : Users)
                    {
                        UserMap.put(usr.id,usr);
                    }
                }
                
                for(Certificate_Data__c certDatum : CertificateData)
                {
                    if(Date.today().daysBetween(certDatum.Expiry_Date__c) <=7 )
                    {
                        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                        mail.setToAddresses(new String[] {UserMap.get(ItemsMap.get(certDatum.Item__c).CreatedById).Email});
                        mail.setSubject('Item Certificate or Licence is about to Expire');
                        mail.setPlainTextBody('Licence for Item '+ItemsMap.get(certDatum.Item__c).name+' will be expired on '+certDatum.Expiry_Date__c+'. Please consider renewing it.');
                        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{ mail });
                    }
                }   
            }  
        }
        catch(Exception ex)
        {
            System.debug(ex);
            ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR,'Process Failed');
            ApexPages.addMessage(myMsg);
        }
    }
}